package com.code.commons.web.resolver;

import com.code.commons.annotations.LoginAuth;
import com.code.user.model.bo.LoginUser;
import com.code.user.token.helper.LoginTokenHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.lang.reflect.Method;

/**
 * 登录用户参数解析器
 *
 * @author tangyifei
 * @since 2019-5-24 11:02:19
 */
@Slf4j
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 根据方法参数判断是否需要对其做转换
     *
     * @param parameter 方法参数
     * @return 对其转换与否
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        final Method method = parameter.getMethod();
        final Class<?> clazz = parameter.getMethod().getDeclaringClass();
        //类或者方法上是否有LoginAuth注解
        boolean isHasLoginAuthAnn = clazz.isAnnotationPresent(LoginAuth.class) || method.isAnnotationPresent(LoginAuth.class);
        //方法的参数类型是否是LoginUser类型
        boolean isHasLoginUserParameter = parameter.getParameterType().isAssignableFrom(LoginUser.class);
        //如果类或者方法上有LoginAuth注解并且方法的参数类型是否是LoginUser类型,那么对方法的参数进行解析并且转化
        return isHasLoginAuthAnn && isHasLoginUserParameter;
    }

    /**
     * supportsParameter方法返回true后，进入resolveArgument方法，返回值即为要转化对象的结果
     *
     * @param parameter     方法参数
     * @param mavContainer  mvc视图容器
     * @param webRequest    本地web请求对象
     * @param binderFactory web数据绑定工厂
     * @return 转换的对象
     * @throws Exception 相关的异常
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //从请求中获取登陆用户的信息
        return LoginTokenHelper.getLoginUserFromRequest();
    }
}
